package com.dy.wind.utils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Hasee
 * @Description TODO 去重
 * @date 2022/3/30-10:28
 */
public class DeduplicationUtils {

    /**
     * @Description: 返回 去重 好的list集合
     * @Param: [list]
     * @return: java.util.List<T>
     * @Author: wind
     * @Date: 2022-03-30 12:56:50-
     **/
    public static <T> List<T> distinctElements(List<T> list) {
        return list.stream().distinct().collect(Collectors.toList());
    }

    /**
     * @Description: 去除集合里 重复 的值
     * @Param: [list]
     * @return: void
     * @Author: wind
     * @Date: 2022-03-30 12:59:21-
     **/
    public static <T> List<T> getNotRepeatingList(List<T> list) {
        Map<T, Long> collect = list.stream().collect(Collectors.groupingBy(t -> t, Collectors.counting()));
        return collect.entrySet().stream()
                .filter(entry -> entry.getValue() == 1)
                .map(Map.Entry::getKey).collect(Collectors.toList());
    }

    /**
     * @Description: 查找集合中 重复的 元素
     * @Param: [list]
     * @return: java.util.List<T>
     * @Author: wind
     * @Date: 2022-03-30 14:15:47-
     **/
    public static <T> List<T> getRepeatingList(List<T> list) {
        return list.stream().collect(Collectors.collectingAndThen(
                Collectors.groupingBy(t -> t, Collectors.counting()), map -> {
                    map.values().removeIf(size -> size == 1);
                    return (List<T>) new ArrayList<T>(map.keySet());
                })
        );
    }

    /**
     * @Description: 根据对象属性去重
     * @Param: [list, methodName] 
     * @return: java.util.List<T> 
     * @Author: wind
     * @Date: 2022-03-31 16:42:55-
     **/
    public static <T> List<T> removeIfDuplicate(List<T> list, String methodName) throws Exception {
        if (list.size() < 2) {
            return list;
        }
        Set<Object> aux = new HashSet<>();
        for (int i = list.size() - 1; i >= 0; i--) {
            T entity = list.get(i);
            if (!aux.add(entity.getClass().getMethod(methodName).invoke(entity))) {
                list.remove(entity);
            }
        }
        return list;
    }
}
